﻿// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证（版本 2.0）进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动！任何基于本项目二次开发而产生的一切法律纠纷和责任，我们不承担任何责任！

using Admin.NET.Core.Service;
using Aop.Api.Domain;
using Microsoft.AspNetCore.Http;

namespace Admin.NET.Application;

/// <summary>
/// 车辆求购信息表服务 🧩
/// </summary>
[ApiDescriptionSettings(ApplicationConst.GroupName, Order = 100)]
public class AppVehiclePurchaseService : IDynamicApiController, ITransient
{
    private readonly SqlSugarRepository<AppVehiclePurchase> _appVehiclePurchaseRep;
    private readonly ISqlSugarClient _sqlSugarClient;
    private readonly UserManager _userManager;

    public AppVehiclePurchaseService(SqlSugarRepository<AppVehiclePurchase> appVehiclePurchaseRep, ISqlSugarClient sqlSugarClient, UserManager userManager)
    {
        _appVehiclePurchaseRep = appVehiclePurchaseRep;
        _sqlSugarClient = sqlSugarClient;
        _userManager = userManager;

    }

    /// <summary>
    /// 分页查询车辆求购信息表 🔖
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [DisplayName("分页查询车辆求购信息表")]
    [ApiDescriptionSettings(Name = "Page"), HttpPost]
    [AllowAnonymous]
    public async Task<SqlSugarPagedList<AppVehiclePurchaseOutput>> Page(PageAppVehiclePurchaseInput input)
    {
        input.Keyword = input.Keyword?.Trim();
        var query = _appVehiclePurchaseRep.AsQueryable()
            .WhereIF(input.BuyerId != null, u => u.BuyerId == input.BuyerId)
            .WhereIF(input.RegionId != null, u => u.RegionId == input.RegionId)
            .WhereIF(input.SourceRegionId != null, u => u.SourceRegionId == input.SourceRegionId)
            .WhereIF(input.Type.HasValue, u => u.Type == input.Type)
            .WhereIF(input.BrandId != null, u => u.BrandId == input.BrandId)
            .WhereIF(input.ModelId != null, u => u.ModelId == input.ModelId)
            .WhereIF(input.ExteriorColor.HasValue, u => u.ExteriorColor == input.ExteriorColor)
            .WhereIF(input.Status.HasValue, u => u.Status == input.Status)
            .LeftJoin<SysUser>((u, buyer) => u.BuyerId == buyer.Id)
            .LeftJoin<SysRegion>((u, buyer, region) => u.RegionId == region.Code)
            .LeftJoin<AppVehicleBrand>((u, buyer, region, brand) => u.BrandId == brand.Id)
            .LeftJoin<AppVehicleModel>((u, buyer, region, brand, model) => u.ModelId == model.Id)
            .LeftJoin<SysRegion>((u, buyer, region, brand, model,region2) => u.SourceRegionId == region2.Code)
                        .WhereIF(string.IsNullOrEmpty(input.Keyword), (u, buyer, region, brand, model, region2) => brand.Name.Contains(input.Keyword) || model.Name.Contains(input.Keyword))
            .Select((u, buyer, region, brand, model, region2) => new AppVehiclePurchaseOutput
            {
                Id = u.Id,
                BuyerId = u.BuyerId,
                BuyerFkDisplayName = $"{buyer.RealName}",
                BuyerAvatar = buyer.Avatar,
                RegionId = u.RegionId,
                RegionFkDisplayName = $"{region.Name}",
                SourceRegionId = u.SourceRegionId,
                SourceRegionFkDisplayName = $"{region2.Name}",
                Type = u.Type,
                BrandId = u.BrandId,
                BrandFkDisplayName = $"{brand.Name}",
                ModelId = u.ModelId,
                ModelFkDisplayName = $"{model.Name}",
                ExteriorColor = u.ExteriorColor,
                InteriorColor = u.InteriorColor,
                OptionalConfigs = u.OptionalConfigs,
                FullPaymentBudget = u.FullPaymentBudget,
                InstallmentDownPayment = u.InstallmentDownPayment,
                MonthlyPayment = u.MonthlyPayment,
                AcceptTradeIn = u.AcceptTradeIn,
                ConditionRequirement = u.ConditionRequirement,
                RegisterYearFrom = u.RegisterYearFrom,
                RegisterYearTo = u.RegisterYearTo,
                BudgetMin = u.BudgetMin,
                BudgetMax = u.BudgetMax,
                ExpectedMileage = u.ExpectedMileage,
                AdditionalRequirements = u.AdditionalRequirements,
                Remark = u.Remark,
                Status = u.Status,
                TenantId = u.TenantId,
                CreateTime = u.CreateTime,
                UpdateTime = u.UpdateTime,
                CreateUserId = u.CreateUserId,
                CreateUserName = u.CreateUserName,
                UpdateUserId = u.UpdateUserId,
                UpdateUserName = u.UpdateUserName,
                IsDelete = u.IsDelete,
            });
        var result = await query.OrderBuilder(input).ToPagedListAsync(input.Page, input.PageSize);
        foreach (var item in result.Items)
        {
            item.TypeName = item.Type.GetDescription();
            item.ConditionRequirementName = item.ConditionRequirement.GetDescription();
            item.ExteriorColorName = item.ExteriorColor.GetDescription();
            item.InteriorColorName = item.InteriorColor.GetDescription();

        }
        return result;
    }

    /// <summary>
    /// 查询车辆求购信息表 🔖
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [DisplayName("分查询车辆求购信息表")]
    [ApiDescriptionSettings(Name = "List"), HttpPost]
    [AllowAnonymous]
    public async Task<List<AppVehiclePurchaseOutput>> List(VehiclePurchaseUserInput input)
    {
        var query = _appVehiclePurchaseRep.AsQueryable()
            .WhereIF(input.BuyerId != null, u => u.BuyerId == _userManager.UserId)
            .WhereIF(input.RegionId != null, u => u.RegionId == input.RegionId)
            .WhereIF(input.SourceRegionId != null, u => u.SourceRegionId == input.SourceRegionId)
            .WhereIF(input.Type.HasValue, u => u.Type == input.Type)
            .WhereIF(input.BrandId != null, u => u.BrandId == input.BrandId)
            .WhereIF(input.ModelId != null, u => u.ModelId == input.ModelId)
            .WhereIF(input.ExteriorColor.HasValue, u => u.ExteriorColor == input.ExteriorColor)
            .WhereIF(input.Status.HasValue, u => u.Status == input.Status)
            .LeftJoin<SysUser>((u, buyer) => u.BuyerId == buyer.Id)
            .LeftJoin<SysRegion>((u, buyer, region) => u.RegionId == region.Code)
            .LeftJoin<AppVehicleBrand>((u, buyer, region, brand) => u.BrandId == brand.Id)
            .LeftJoin<AppVehicleModel>((u, buyer, region, brand, model) => u.ModelId == model.Id)
            .LeftJoin<SysRegion>((u, buyer, region, brand, model, region2) => u.SourceRegionId == region2.Code)
            //            .WhereIF(string.IsNullOrEmpty(input.Keyword), (u, buyer, region, brand, model, region2) => brand.Name.Contains(input.Keyword) || model.Name.Contains(input.Keyword))
            .Select((u, buyer, region, brand, model, region2) => new AppVehiclePurchaseOutput
            {
                Id = u.Id,
                BuyerId = u.BuyerId,
                BuyerFkDisplayName = $"{buyer.RealName}",
                BuyerAvatar = buyer.Avatar,
                RegionId = u.RegionId,
                RegionFkDisplayName = $"{region.Name}",
                SourceRegionId = u.SourceRegionId,
                SourceRegionFkDisplayName = $"{region2.Name}",
                Type = u.Type,
                BrandId = u.BrandId,
                BrandFkDisplayName = $"{brand.Name}",
                ModelId = u.ModelId,
                ModelFkDisplayName = $"{model.Name}",
                ExteriorColor = u.ExteriorColor,
                InteriorColor = u.InteriorColor,
                OptionalConfigs = u.OptionalConfigs,
                FullPaymentBudget = u.FullPaymentBudget,
                InstallmentDownPayment = u.InstallmentDownPayment,
                MonthlyPayment = u.MonthlyPayment,
                AcceptTradeIn = u.AcceptTradeIn,
                ConditionRequirement = u.ConditionRequirement,
                RegisterYearFrom = u.RegisterYearFrom,
                RegisterYearTo = u.RegisterYearTo,
                BudgetMin = u.BudgetMin,
                BudgetMax = u.BudgetMax,
                ExpectedMileage = u.ExpectedMileage,
                AdditionalRequirements = u.AdditionalRequirements,
                Remark = u.Remark,
                Status = u.Status,
                TenantId = u.TenantId,
                CreateTime = u.CreateTime,
                UpdateTime = u.UpdateTime,
                CreateUserId = u.CreateUserId,
                CreateUserName = u.CreateUserName,
                UpdateUserId = u.UpdateUserId,
                UpdateUserName = u.UpdateUserName,
                IsDelete = u.IsDelete,
            });
        var result = await query.ToListAsync();
        foreach (var item in result)
        {
            item.TypeName = item.Type.GetDescription();
            item.ConditionRequirementName = item.ConditionRequirement.GetDescription();
            item.ExteriorColorName = item.ExteriorColor.GetDescription();
            item.InteriorColorName = item.InteriorColor.GetDescription();
        }
        return result;
    }

    /// <summary>
    /// 我的分页查询车辆求购信息表 🔖
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [DisplayName("我的分页查询车辆求购信息表")]
    [ApiDescriptionSettings(Name = "MyPage"), HttpPost]
    [AllowAnonymous]
    public async Task<SqlSugarPagedList<AppVehiclePurchaseOutput>> MyPage(PageAppVehiclePurchaseInput input)
    {
        input.Keyword = input.Keyword?.Trim();
        var query = _appVehiclePurchaseRep.AsQueryable()
            .Where(u => u.BuyerId == _userManager.UserId)
            .WhereIF(input.BuyerId != null, u => u.BuyerId == input.BuyerId)
            .WhereIF(input.RegionId != null, u => u.RegionId == input.RegionId)
            .WhereIF(input.Type.HasValue, u => u.Type == input.Type)
            .WhereIF(input.BrandId != null, u => u.BrandId == input.BrandId)
            .WhereIF(input.ModelId != null, u => u.ModelId == input.ModelId)
            .WhereIF(input.ExteriorColor.HasValue, u => u.ExteriorColor == input.ExteriorColor)
            .WhereIF(input.Status.HasValue, u => u.Status == input.Status)
            .LeftJoin<SysUser>((u, buyer) => u.BuyerId == buyer.Id)
            .LeftJoin<SysRegion>((u, buyer, region) => u.RegionId == region.Code)
            .LeftJoin<AppVehicleBrand>((u, buyer, region, brand) => u.BrandId == brand.Id)
            .LeftJoin<AppVehicleModel>((u, buyer, region, brand, model) => u.ModelId == model.Id)
            .LeftJoin<SysRegion>((u, buyer, region, brand, model, region2) => u.SourceRegionId == region2.Code)
            .Select((u, buyer, region, brand, model, region2) => new AppVehiclePurchaseOutput
            {
                Id = u.Id,
                BuyerId = u.BuyerId,
                BuyerFkDisplayName = $"{buyer.RealName}",
                RegionId = u.RegionId,
                RegionFkDisplayName = $"{region.Name}",
                SourceRegionId = u.SourceRegionId,
                SourceRegionFkDisplayName = $"{region2.Name}",
                Type = u.Type,
                BrandId = u.BrandId,
                BrandFkDisplayName = $"{brand.Name}",
                ModelId = u.ModelId,
                ModelFkDisplayName = $"{model.Name}",
                ExteriorColor = u.ExteriorColor,
                InteriorColor = u.InteriorColor,
                OptionalConfigs = u.OptionalConfigs,
                FullPaymentBudget = u.FullPaymentBudget,
                InstallmentDownPayment = u.InstallmentDownPayment,
                MonthlyPayment = u.MonthlyPayment,
                AcceptTradeIn = u.AcceptTradeIn,
                ConditionRequirement = u.ConditionRequirement,
                RegisterYearFrom = u.RegisterYearFrom,
                RegisterYearTo = u.RegisterYearTo,
                BudgetMin = u.BudgetMin,
                BudgetMax = u.BudgetMax,
                ExpectedMileage = u.ExpectedMileage,
                AdditionalRequirements = u.AdditionalRequirements,
                Remark = u.Remark,
                Status = u.Status,
                BidCount = SqlFunc.Subqueryable<AppVehicleBid>().Where(b => b.PurchaseId == u.Id && b.IsDelete == false).Count(),
                TenantId = u.TenantId,
                CreateTime = u.CreateTime,
                UpdateTime = u.UpdateTime,
                CreateUserId = u.CreateUserId,
                CreateUserName = u.CreateUserName,
                UpdateUserId = u.UpdateUserId,
                UpdateUserName = u.UpdateUserName,
                IsDelete = u.IsDelete,
                Avatar= buyer.Avatar,
            }); ;
        var result = await query.OrderBuilder(input).ToPagedListAsync(input.Page, input.PageSize);
        foreach (var item in result.Items)
        {
            item.TypeName = item.Type.GetDescription();
            item.ConditionRequirementName = item.ConditionRequirement.GetDescription();
            item.ExteriorColorName = item.ExteriorColor.GetDescription();
            item.InteriorColorName = item.InteriorColor.GetDescription();
        }
        return result;
    }
    /// <summary>
    /// 获取车辆求购信息表详情 ℹ️
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [DisplayName("获取车辆求购信息表详情")]
    [ApiDescriptionSettings(Name = "Detail"), HttpGet]
    public async Task<AppVehiclePurchaseOutput> Detail([FromQuery] QueryByIdAppVehiclePurchaseInput input)
    {
        var query = _appVehiclePurchaseRep.AsQueryable()
             .Where(u => u.Id == input.Id)
             .LeftJoin<SysUser>((u, buyer) => u.BuyerId == buyer.Id)
             .LeftJoin<SysRegion>((u, buyer, region) => u.RegionId == region.Code)
             .LeftJoin<AppVehicleBrand>((u, buyer, region, brand) => u.BrandId == brand.Id)
            .LeftJoin<AppVehicleModel>((u, buyer, region, brand, model) => u.ModelId == model.Id)
            .LeftJoin<SysRegion>((u, buyer, region, brand, model, region2) => u.SourceRegionId == region2.Code)
            .Select((u, buyer, region, brand, model, region2) => new AppVehiclePurchaseOutput
            {
                Id = u.Id,
                BuyerId = u.BuyerId,
                BuyerFkDisplayName = $"{buyer.RealName}",
                BuyerAvatar = buyer.Avatar,
                RegionId = u.RegionId,
                RegionFkDisplayName = $"{region.Name}",
                SourceRegionId = u.SourceRegionId,
                SourceRegionFkDisplayName = $"{region2.Name}",
                Type = u.Type,
                BrandId = u.BrandId,
                 BrandFkDisplayName = $"{brand.Name}",
                 ModelId = u.ModelId,
                 ModelFkDisplayName = $"{model.Name}",
                 ExteriorColor = u.ExteriorColor,
                 InteriorColor = u.InteriorColor,
                 OptionalConfigs = u.OptionalConfigs,
                 FullPaymentBudget = u.FullPaymentBudget,
                 InstallmentDownPayment = u.InstallmentDownPayment,
                 MonthlyPayment = u.MonthlyPayment,
                 AcceptTradeIn = u.AcceptTradeIn,
                 ConditionRequirement = u.ConditionRequirement,
                 RegisterYearFrom = u.RegisterYearFrom,
                 RegisterYearTo = u.RegisterYearTo,
                 BudgetMin = u.BudgetMin,
                 BudgetMax = u.BudgetMax,
                 ExpectedMileage = u.ExpectedMileage,
                 AdditionalRequirements = u.AdditionalRequirements,
                 Remark = u.Remark,
                 Status = u.Status,
                 TenantId = u.TenantId,
                 CreateTime = u.CreateTime,
                 UpdateTime = u.UpdateTime,
                 CreateUserId = u.CreateUserId,
                 CreateUserName = u.CreateUserName,
                 UpdateUserId = u.UpdateUserId,
                 UpdateUserName = u.UpdateUserName,
                 IsDelete = u.IsDelete,
                 IsSelf = u.CreateUserId == _userManager.UserId,
             });
        var result = await query.FirstAsync();
        if (result != null)
        {
            result.TypeName = result.Type.GetDescription();
            result.ConditionRequirementName = result.ConditionRequirement.GetDescription();
            result.ExteriorColorName = result.ExteriorColor.GetDescription();
            result.InteriorColorName = result.InteriorColor.GetDescription();
        }
        return result;
    }

    /// <summary>
    /// 增加车辆求购信息表 ➕
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [DisplayName("增加车辆求购信息表")]
    [ApiDescriptionSettings(Name = "Add"), HttpPost]
    public async Task<long> Add(AddAppVehiclePurchaseInput input)
    {
        input.BuyerId = _userManager.UserId;
        var entity = input.Adapt<AppVehiclePurchase>();
        return await _appVehiclePurchaseRep.InsertAsync(entity) ? entity.Id : 0;
    }

    /// <summary>
    /// 更新车辆求购信息表 ✏️
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [DisplayName("更新车辆求购信息表")]
    [ApiDescriptionSettings(Name = "Update"), HttpPost]
    public async Task Update(UpdateAppVehiclePurchaseInput input)
    {
        var entity = input.Adapt<AppVehiclePurchase>();
        await _appVehiclePurchaseRep.AsUpdateable(entity)
        .ExecuteCommandAsync();
    }

    /// <summary>
    /// 更新车辆求购信息表状态 ✏️
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [DisplayName("更新车辆求购信息表状态")]
    [ApiDescriptionSettings(Name = "UpdateStatus"), HttpPost]
    public async Task UpdateStatus(UpdateAppVehiclePurchaseInput input)
    {
        var entity = input.Adapt<AppVehiclePurchase>();
        await _appVehiclePurchaseRep.AsUpdateable(entity).UpdateColumns(u => new { u.Status })
        .ExecuteCommandAsync();
    }

    /// <summary>
    /// 删除车辆求购信息表 ❌
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [DisplayName("删除车辆求购信息表")]
    [ApiDescriptionSettings(Name = "Delete"), HttpPost]
    public async Task Delete(DeleteAppVehiclePurchaseInput input)
    {
        var entity = await _appVehiclePurchaseRep.GetFirstAsync(u => u.Id == input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D1002);
        await _appVehiclePurchaseRep.FakeDeleteAsync(entity);   //假删除
        //await _appVehiclePurchaseRep.DeleteAsync(entity);   //真删除
    }

    /// <summary>
    /// 批量删除车辆求购信息表 ❌
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [DisplayName("批量删除车辆求购信息表")]
    [ApiDescriptionSettings(Name = "BatchDelete"), HttpPost]
    public async Task<int> BatchDelete([Required(ErrorMessage = "主键列表不能为空")] List<DeleteAppVehiclePurchaseInput> input)
    {
        var exp = Expressionable.Create<AppVehiclePurchase>();
        foreach (var row in input) exp = exp.Or(it => it.Id == row.Id);
        var list = await _appVehiclePurchaseRep.AsQueryable().Where(exp.ToExpression()).ToListAsync();

        return await _appVehiclePurchaseRep.FakeDeleteAsync(list);   //假删除
        //return await _appVehiclePurchaseRep.DeleteAsync(list);   //真删除
    }

    /// <summary>
    /// 获取下拉列表数据 🔖
    /// </summary>
    /// <returns></returns>
    [DisplayName("获取下拉列表数据")]
    [ApiDescriptionSettings(Name = "DropdownData"), HttpPost]
    public async Task<Dictionary<string, dynamic>> DropdownData(DropdownDataAppVehiclePurchaseInput input)
    {
        var buyerIdData = await _appVehiclePurchaseRep.Context.Queryable<SysUser>()
            .InnerJoinIF<AppVehiclePurchase>(input.FromPage, (u, r) => u.Id == r.BuyerId)
            .Select(u => new
            {
                Value = u.Id,
                Label = $"{u.RealName}"
            }).ToListAsync();
        var regionIdData = await _appVehiclePurchaseRep.Context.Queryable<SysRegion>()
            .InnerJoinIF<AppVehiclePurchase>(input.FromPage, (u, r) => u.Code == r.RegionId)
            .Select(u => new
            {
                Value = u.Code,
                Label = $"{u.Name}"
            }).ToListAsync();
        var brandIdData = await _appVehiclePurchaseRep.Context.Queryable<AppVehicleBrand>()
            .InnerJoinIF<AppVehiclePurchase>(input.FromPage, (u, r) => u.Id == r.BrandId)
            .Select(u => new
            {
                Value = u.Id,
                Label = $"{u.Name}"
            }).ToListAsync();
        var modelIdData = await _appVehiclePurchaseRep.Context.Queryable<AppVehicleModel>()
            .InnerJoinIF<AppVehiclePurchase>(input.FromPage, (u, r) => u.Id == r.ModelId)
            .Select(u => new
            {
                Value = u.Id,
                Label = $"{u.Name}"
            }).ToListAsync();
        return new Dictionary<string, dynamic>
        {
            { "buyerId", buyerIdData },
            { "regionId", regionIdData },
            { "brandId", brandIdData },
            { "modelId", modelIdData },
        };
    }

    /// <summary>
    /// 导出车辆求购信息表记录 🔖
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [DisplayName("导出车辆求购信息表记录")]
    [ApiDescriptionSettings(Name = "Export"), HttpPost, NonUnify]
    public async Task<IActionResult> Export(PageAppVehiclePurchaseInput input)
    {
        var list = (await Page(input)).Items?.Adapt<List<ExportAppVehiclePurchaseOutput>>() ?? new();
        if (input.SelectKeyList?.Count > 0) list = list.Where(x => input.SelectKeyList.Contains(x.Id)).ToList();
        return ExcelHelper.ExportTemplate(list, "车辆求购信息表导出记录");
    }

    /// <summary>
    /// 下载车辆求购信息表数据导入模板 ⬇️
    /// </summary>
    /// <returns></returns>
    [DisplayName("下载车辆求购信息表数据导入模板")]
    [ApiDescriptionSettings(Name = "Import"), HttpGet, NonUnify]
    public IActionResult DownloadTemplate()
    {
        return ExcelHelper.ExportTemplate(new List<ExportAppVehiclePurchaseOutput>(), "车辆求购信息表导入模板", (_, info) =>
        {
            if (nameof(ExportAppVehiclePurchaseOutput.BuyerFkDisplayName) == info.Name) return _appVehiclePurchaseRep.Context.Queryable<SysUser>().Select(u => $"{u.RealName}").Distinct().ToList();
            if (nameof(ExportAppVehiclePurchaseOutput.RegionFkDisplayName) == info.Name) return _appVehiclePurchaseRep.Context.Queryable<SysRegion>().Select(u => $"{u.Name}").Distinct().ToList();
            if (nameof(ExportAppVehiclePurchaseOutput.BrandFkDisplayName) == info.Name) return _appVehiclePurchaseRep.Context.Queryable<AppVehicleBrand>().Select(u => $"{u.Name}").Distinct().ToList();
            if (nameof(ExportAppVehiclePurchaseOutput.ModelFkDisplayName) == info.Name) return _appVehiclePurchaseRep.Context.Queryable<AppVehicleModel>().Select(u => $"{u.Name}").Distinct().ToList();
            return null;
        });
    }

    /// <summary>
    /// 导入车辆求购信息表记录 💾
    /// </summary>
    /// <returns></returns>
    [DisplayName("导入车辆求购信息表记录")]
    [ApiDescriptionSettings(Name = "Import"), HttpPost, NonUnify, UnitOfWork]
    public IActionResult ImportData([Required] IFormFile file)
    {
        lock (this)
        {
            var stream = ExcelHelper.ImportData<ImportAppVehiclePurchaseInput, AppVehiclePurchase>(file, (list, markerErrorAction) =>
            {
                _sqlSugarClient.Utilities.PageEach(list, 2048, pageItems =>
                {
                    // 链接 买家Id
                    var buyerIdLabelList = pageItems.Where(x => x.BuyerFkDisplayName != null).Select(x => x.BuyerFkDisplayName).Distinct().ToList();
                    if (buyerIdLabelList.Any())
                    {
                        var buyerIdLinkMap = _appVehiclePurchaseRep.Context.Queryable<SysUser>().Where(u => buyerIdLabelList.Contains($"{u.RealName}")).ToList().ToDictionary(u => $"{u.RealName}", u => u.Id);
                        pageItems.ForEach(e =>
                        {
                            e.BuyerId = buyerIdLinkMap.GetValueOrDefault(e.BuyerFkDisplayName ?? "");
                            if (e.BuyerId == null) e.Error = "买家Id链接失败";
                        });
                    }
                    // 链接 上牌地区Id
                    var regionIdLabelList = pageItems.Where(x => x.RegionFkDisplayName != null).Select(x => x.RegionFkDisplayName).Distinct().ToList();
                    if (regionIdLabelList.Any())
                    {
                        var regionIdLinkMap = _appVehiclePurchaseRep.Context.Queryable<SysRegion>().Where(u => regionIdLabelList.Contains($"{u.Name}")).ToList().ToDictionary(u => $"{u.Name}", u => u.Code);
                        pageItems.ForEach(e =>
                        {
                            e.RegionId = regionIdLinkMap.GetValueOrDefault(e.RegionFkDisplayName ?? "");
                            if (e.RegionId == null) e.Error = "上牌地区Id链接失败";
                        });
                    }
                    // 链接 期望品牌
                    var brandIdLabelList = pageItems.Where(x => x.BrandFkDisplayName != null).Select(x => x.BrandFkDisplayName).Distinct().ToList();
                    if (brandIdLabelList.Any())
                    {
                        var brandIdLinkMap = _appVehiclePurchaseRep.Context.Queryable<AppVehicleBrand>().Where(u => brandIdLabelList.Contains($"{u.Name}")).ToList().ToDictionary(u => $"{u.Name}", u => u.Id);
                        pageItems.ForEach(e =>
                        {
                            e.BrandId = brandIdLinkMap.GetValueOrDefault(e.BrandFkDisplayName ?? "");
                            if (e.BrandId == null) e.Error = "期望品牌链接失败";
                        });
                    }
                    // 链接 期望车型
                    var modelIdLabelList = pageItems.Where(x => x.ModelFkDisplayName != null).Select(x => x.ModelFkDisplayName).Distinct().ToList();
                    if (modelIdLabelList.Any())
                    {
                        var modelIdLinkMap = _appVehiclePurchaseRep.Context.Queryable<AppVehicleModel>().Where(u => modelIdLabelList.Contains($"{u.Name}")).ToList().ToDictionary(u => $"{u.Name}", u => u.Id);
                        pageItems.ForEach(e =>
                        {
                            e.ModelId = modelIdLinkMap.GetValueOrDefault(e.ModelFkDisplayName ?? "");
                            if (e.ModelId == null) e.Error = "期望车型链接失败";
                        });
                    }

                    // 校验并过滤必填基本类型为null的字段
                    var rows = pageItems.Where(x =>
                    {
                        if (!string.IsNullOrWhiteSpace(x.Error)) return false;
                        if (x.BuyerId == null)
                        {
                            x.Error = "买家Id不能为空";
                            return false;
                        }
                        if (!string.IsNullOrWhiteSpace(x.Error)) return false;
                        if (x.RegionId == null)
                        {
                            x.Error = "上牌地区Id不能为空";
                            return false;
                        }
                        if (!string.IsNullOrWhiteSpace(x.Error)) return false;
                        if (x.Type == null)
                        {
                            x.Error = "类型不能为空";
                            return false;
                        }
                        if (!string.IsNullOrWhiteSpace(x.Error)) return false;
                        if (x.BrandId == null)
                        {
                            x.Error = "期望品牌不能为空";
                            return false;
                        }
                        if (!string.IsNullOrWhiteSpace(x.Error)) return false;
                        if (x.ModelId == null)
                        {
                            x.Error = "期望车型不能为空";
                            return false;
                        }
                        return true;
                    }).Adapt<List<AppVehiclePurchase>>();

                    var storageable = _appVehiclePurchaseRep.Context.Storageable(rows)
                        .SplitError(it => it.Item.BrandId == null, "期望品牌不能为空")
                        .SplitError(it => it.Item.ModelId == null, "期望车型不能为空")
                        .SplitError(it => it.Item.OptionalConfigs?.Length > 128, "选装配置长度不能超过128个字符")
                        .SplitError(it => it.Item.AdditionalRequirements?.Length > 500, "补充要求长度不能超过500个字符")
                        .SplitError(it => it.Item.Remark?.Length > 128, "备注长度不能超过128个字符")
                        .SplitInsert(_ => true)
                        .ToStorage();

                    storageable.BulkCopy();
                    storageable.BulkUpdate();

                    // 标记错误信息
                    markerErrorAction.Invoke(storageable, pageItems, rows);
                });
            });

            return stream;
        }
    }

    #region 

    #endregion
}
